package edu.wit.system.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.map.MapUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.github.pagehelper.PageInfo;
import edu.wit.common.constant.AffairsConstant;
import edu.wit.common.constant.CommonConstant;
import edu.wit.common.db.page.TableSupport;
import edu.wit.common.db.service.impl.BaseServiceImpl;
import edu.wit.common.exception.CustomException;
import edu.wit.common.exception.HgException;
import edu.wit.common.exception.ResultEnums;
import edu.wit.common.security.service.TokenService;
import edu.wit.common.utils.UUIDGenUtil;
import edu.wit.common.web.PageResult;
import edu.wit.system.domain.*;
import edu.wit.system.domain.dto.AffairsWorkflowDto;
import edu.wit.system.domain.dto.AffairsWorkflowNodeDto;
import edu.wit.system.domain.dto.AffairsWorkflowNodeUserDto;
import edu.wit.system.domain.vo.AffairsWorkflowNodeUserVo;
import edu.wit.system.domain.vo.AffairsWorkflowNodeVo;
import edu.wit.system.domain.vo.AffairsWorkflowVo;
import edu.wit.system.domain.vo.Corporation;
import edu.wit.system.mapper.AffairsApplyWorkflowMapper;
import edu.wit.system.mapper.AffairsWorkflowMapper;
import edu.wit.system.service.AffairsWorkflowNodeService;
import edu.wit.system.service.AffairsWorkflowNodeUserService;
import edu.wit.system.service.AffairsWorkflowService;
//import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import static edu.wit.common.exception.ResultEnums.LOGIC_ERROR;


@Service("affairsWorkflowService")
public class AffairsWorkflowServiceImpl extends BaseServiceImpl<AffairsWorkflowMapper, AffairsWorkflow> implements AffairsWorkflowService {

	@Autowired
	private AffairsWorkflowNodeService affairsWorkflowNodeService;

	@Autowired
	private AffairsWorkflowNodeUserService affairsWorkflowNodeUserService;

	@Autowired
	private TokenService tokenService;

	@Autowired
	private AffairsApplyWorkflowMapper affairsApplyWorkflowMapper;

	@Autowired
	private AffairsWorkflowMapper affairsWorkflowMapper;

    @Override
    public PageResult<AffairsWorkflowDto> queryPage(Map<String, Object> params) {
//        params.put("visible", CommonConstant.YesNo.YES_INT);
//		params.put("visible", 0);

        TableSupport.startPage(null);
        List<AffairsWorkflowDto> result = baseMapper.getTableList(params);
		List<Corporation> corporations = baseMapper.selectCompany();

		for (AffairsWorkflowDto workflowDto : result) {
			for (Corporation corporation : corporations) {
				if(workflowDto.getCorporation().equals(corporation.getId())) {
					workflowDto.setCorpName(corporation.getCompanyName());
				}
			}
		}

		PageInfo<AffairsWorkflowDto> pageInfo = new PageInfo<>(result);
		List<AffairsWorkflowDto> list = pageInfo.getList();

		return PageResult.success(list, pageInfo.getTotal());
    }

    @Override
	public AffairsWorkflowDto getById(Long id) {
    	AffairsWorkflowDto dto = new AffairsWorkflowDto();

		AffairsWorkflow model = baseMapper.selectByWorkflowId(id);

//		System.out.println("model=" + model);
		if (model == null) {
			throw new CustomException(ResultEnums.PARAM_ERROR.getCode(), "ID不存在");
		}

		org.springframework.beans.BeanUtils.copyProperties(model, dto);


		// 根据流程ID查询流程节点信息
		List<AffairsWorkflowNode> nodeList = affairsWorkflowNodeService.getListByWorkflowId(id);
		// 根据流程ID查询流程节点对应审核人员信息
		List<AffairsWorkflowNodeUser> userList = affairsWorkflowNodeUserService.getListByWorkflowId(id);

		Map<Long, List<AffairsWorkflowNodeUserDto>> userMap = MapUtil.newHashMap();

		if(userList != null && userList.size() > 0) {
			for(AffairsWorkflowNodeUser user : userList) {
				AffairsWorkflowNodeUserDto userDto = new AffairsWorkflowNodeUserDto();
				userDto.setExamineUserId(user.getExamineUserId());
//				userDto.setExamineUserName(SysUserUtil.userInfoById(user.getExamineUserId()).getRealName());
				userDto.setExamineUserName(baseMapper.selectUsernameById(user.getExamineUserId() + ""));

				if(userMap.get(user.getWorkflowNodeId()) != null) {
					userMap.get(user.getWorkflowNodeId()).add(userDto);
				} else {
					List<AffairsWorkflowNodeUserDto> tempList = new ArrayList<AffairsWorkflowNodeUserDto>();
					tempList.add(userDto);
					userMap.put(user.getWorkflowNodeId(), tempList);
				}
			}
		}

		List<AffairsWorkflowNodeDto> nodeDtoList = new ArrayList<AffairsWorkflowNodeDto>();
		if(nodeList != null && nodeList.size() > 0) {
			for(AffairsWorkflowNode node : nodeList) {
				AffairsWorkflowNodeDto nodeDto = new AffairsWorkflowNodeDto();
				BeanUtils.copyProperties(node, nodeDto);
				nodeDto.setUserList(userMap.get(node.getWorkflowNodeId()));
				nodeDtoList.add(nodeDto);
			}
		}
		dto.setNodeList(nodeDtoList);

		return dto;
	}

	@Override
    public boolean saveInfo(AffairsWorkflowVo vo){
//		String username = manager.getUserFromToken(ServletUtils.getRequest().getHeader("token"));

		String username = tokenService.getLoginUserByToken().getUsername();
		User user2 = affairsApplyWorkflowMapper.selectUserByUsername(username);
		String projectAdminId = null;
		Long userId = Long.parseLong(user2.getId());

//		if(user2.getPid().equals("0")){
//			 projectAdminId = user2.getId();
//		}else {
//			 projectAdminId = user2.getPid();
//		}
//		vo.setProjectId(Long.parseLong(projectAdminId));

    	AffairsWorkflow affairsWorkflow = Convert.convert(AffairsWorkflow.class, vo);

		QueryWrapper<AffairsWorkflow> wrapper = new QueryWrapper<>();
		wrapper.eq("workflow_type",vo.getWorkflowType());
		wrapper.eq("project_id", vo.getProjectId());
		wrapper.eq("corporation",vo.getCorporation());
		wrapper.eq("visible",0);

		List<AffairsWorkflow> workflows = baseMapper.selectList(wrapper);

		//修改
        if(null != affairsWorkflow.getWorkflowId()){
            affairsWorkflow.setUpdateUserId(userId);
            affairsWorkflow.setUpdateTime(new Date());
//            this.updateById(affairsWorkflow);
			baseMapper.updateById(affairsWorkflow);

			// 根据流程ID删除流程节点信息
            affairsWorkflowNodeService.deleteByWorkflowId(affairsWorkflow.getWorkflowId());
            // 根据流程ID删除流程节点审核人信息
            affairsWorkflowNodeUserService.deleteByWorkflowId(affairsWorkflow.getWorkflowId());

        } else {
			if (workflows.size() >= 1) {
				throw new HgException(LOGIC_ERROR);
			}

            affairsWorkflow.setWorkflowId(UUIDGenUtil.generate());
            affairsWorkflow.setVisible(0);
            affairsWorkflow.setCreateUserId(userId);
			affairsWorkflow.setUpdateUserId(userId);
            affairsWorkflow.setCreateTime(new Date());
			affairsWorkflow.setUpdateTime(new Date());
            this.save(affairsWorkflow);
        }

        List<AffairsWorkflowNode> nodeList = new ArrayList<AffairsWorkflowNode>();
        List<AffairsWorkflowNodeUser> userList = new ArrayList<AffairsWorkflowNodeUser>();


		// 流程节点列表
        List<AffairsWorkflowNodeVo> nodeVoList = vo.getNodeList();
        if(nodeVoList != null && nodeVoList.size() > 0) {
        	int i = 0;
        	for(AffairsWorkflowNodeVo nodeVo : nodeVoList) {
        		i++;
        		AffairsWorkflowNode node = new AffairsWorkflowNode();
        		node.setWorkflowNodeId(UUIDGenUtil.generate());
        		node.setWorkflowNodeName(nodeVo.getWorkflowNodeName());
        		node.setWorkflowNodeIndex(i);
        		node.setWorkflowNodeIslast(nodeVoList.size() == i ? CommonConstant.YesNo.YES : CommonConstant.YesNo.NO);
        		node.setWorkflowId(affairsWorkflow.getWorkflowId());
        		nodeList.add(node);

        		// 流程节点对应的审核人列表
        		List<AffairsWorkflowNodeUserVo> userVoList = nodeVo.getUserList();
        		if(userVoList != null && userVoList.size() > 0) {
        			for(AffairsWorkflowNodeUserVo userVo : userVoList) {
        				AffairsWorkflowNodeUser user = new AffairsWorkflowNodeUser();
        				user.setId(UUIDGenUtil.generate());
        				user.setWorkflowId(affairsWorkflow.getWorkflowId());
        				user.setWorkflowNodeId(node.getWorkflowNodeId());
        				user.setExamineUserId(userVo.getExamineUserId());
        				userList.add(user);
        			}
        		}
        	}

        	// 批量保存
        	if(nodeList != null && nodeList.size() > 0) {
        		affairsWorkflowNodeService.saveBatch(nodeList);
        	}

        	if(userList != null && userList.size() > 0) {
        		affairsWorkflowNodeUserService.saveBatch(userList);
        	}
        }

		return true;
    }

	@Override
    public void delete(List<Long> workflowIds){
//		Long userId = remoteUserinfoService.getIdByUsername(SecurityContextHolder.getContext().getAuthentication().getName());
//		String uesrname = manager.getUserFromToken(ServletUtils.getRequest().getHeader("token"));

		String username = tokenService.getLoginUserByToken().getUsername();
		Long userId = Long.parseLong(baseMapper.selectIdByUsername(username));
		AffairsWorkflow affairsWorkflow = new AffairsWorkflow();
		affairsWorkflow.setVisible(CommonConstant.YesNo.NO_INT);
		affairsWorkflow.setUpdateUserId(userId);
   	 	affairsWorkflow.setUpdateTime(new Date());

   	 	this.baseLogicDelete(affairsWorkflow, new UpdateWrapper<AffairsWorkflow>().lambda().in(AffairsWorkflow::getWorkflowId, workflowIds));
    }

	@Override
	public List<AffairsWorkflowDto> getList(Map<String, Object> params) {
		params.put("visible", 0);
		params.put("workflowStatus", AffairsConstant.WorkflowStatus.ENABLE);
		return baseMapper.getList(params);
	}

	@Override
	public Long selectWorkflowIdByWorkflowTypeAndPid(String workflowType) {
		String username = tokenService.getLoginUserByToken().getUsername();
        User user = affairsApplyWorkflowMapper.selectUserByUsername(username);
		String pid = user.getPid().equals("0") ? user.getId() : user.getPid();

//		String projectId = ServletUtils.getRequest().getHeader("projectId");

		QueryWrapper<AffairsWorkflow> wrapper = new QueryWrapper<>();
		wrapper.eq("workflow_type",workflowType)
				.eq("project_id",pid);
		return baseMapper.selectOne(wrapper).getWorkflowId();
	}

	@Override
	public List<AffairsWorkflowDto> selectWorkflowList(String projectId, String serviceCorporationId,String workflowType) {
		return affairsWorkflowMapper.selectWorkflowList(projectId,serviceCorporationId,workflowType);
	}

	@Override
	public boolean saveWageWorkflow(AffairsWorkflowVo affairsWorkflowVo) {
		String username = tokenService.getLoginUserByToken().getUsername();
		Long userId = Long.parseLong(affairsApplyWorkflowMapper.selectUserByUsername(username).getId());
		AffairsWorkflow affairsWorkflow = Convert.convert(AffairsWorkflow.class, affairsWorkflowVo);

		QueryWrapper<AffairsWorkflow> wrapper = new QueryWrapper<>();
		wrapper.eq("workflow_type", affairsWorkflowVo.getWorkflowType());
		wrapper.eq("project_id", affairsWorkflowVo.getProjectId());
		wrapper.eq("corporation", affairsWorkflowVo.getCorporation());
		wrapper.eq("visible", 0);
		List<AffairsWorkflow> workflows = baseMapper.selectList(wrapper);


		List<AffairsWorkflowNode> nodeList = new ArrayList<AffairsWorkflowNode>();
		List<AffairsWorkflowNodeUser> userList = new ArrayList<AffairsWorkflowNodeUser>();
		int i = 0;

		//修改
		if (null != affairsWorkflow.getWorkflowId()) {
			affairsWorkflow.setUpdateUserId(userId);
			affairsWorkflow.setUpdateTime(new Date());
//            this.updateById(affairsWorkflow);
			baseMapper.updateById(affairsWorkflow);

			// 根据流程ID删除流程节点信息
			affairsWorkflowNodeService.deleteByWorkflowId(affairsWorkflow.getWorkflowId());
			// 根据流程ID删除流程节点审核人信息
			affairsWorkflowNodeUserService.deleteByWorkflowId(affairsWorkflow.getWorkflowId());

		} else {
			//每个劳务公司仅能拥有一个流程类型的流程
			if (workflows.size() >= 1) {
				throw new HgException(LOGIC_ERROR);
			}

			affairsWorkflow.setWorkflowId(UUIDGenUtil.generate());
			affairsWorkflow.setVisible(0);
			affairsWorkflow.setWorkflowType(affairsWorkflowVo.getWorkflowType());
			affairsWorkflow.setWorkflowName(affairsWorkflowVo.getWorkflowName());
			affairsWorkflow.setWorkflowRemark(affairsWorkflowVo.getWorkflowRemark());
			affairsWorkflow.setCorporation(affairsWorkflowVo.getCorporation());
			affairsWorkflow.setProjectId(affairsWorkflowVo.getProjectId());
			affairsWorkflow.setWorkflowStatus("1");
			affairsWorkflow.setCreateUserId(userId);
			affairsWorkflow.setUpdateUserId(userId);
			affairsWorkflow.setCreateTime(new Date());
			affairsWorkflow.setUpdateTime(new Date());
			this.save(affairsWorkflow);


			//判断是不是工资审批流程===》在此添加两个nodeList节点(工人节点、班组长节点)
			AffairsWorkflowNode teamNode = new AffairsWorkflowNode();
			AffairsWorkflowNode workerNode = new AffairsWorkflowNode();

			AffairsWorkflowNodeUser teamNodeUser = new AffairsWorkflowNodeUser();
			AffairsWorkflowNodeUser workerNodeUser = new AffairsWorkflowNodeUser();

			teamNode.setWorkflowNodeId(UUIDGenUtil.generate());
			teamNode.setWorkflowNodeName("班组长审批");
			teamNode.setWorkflowNodeIndex(1);
			teamNode.setWorkflowNodeIslast(CommonConstant.YesNo.NO);
			teamNode.setWorkflowId(affairsWorkflow.getWorkflowId());
			nodeList.add(teamNode);

			teamNodeUser.setId(UUIDGenUtil.generate());
			teamNodeUser.setWorkflowId(affairsWorkflow.getWorkflowId());
			teamNodeUser.setWorkflowNodeId(teamNode.getWorkflowNodeId());
			teamNodeUser.setExamineUserId(0L);
			userList.add(teamNodeUser);

			workerNode.setWorkflowNodeId(UUIDGenUtil.generate());
			workerNode.setWorkflowNodeName("工人审批");
			workerNode.setWorkflowNodeIndex(2);
			workerNode.setWorkflowNodeIslast(CommonConstant.YesNo.NO);
			workerNode.setWorkflowId(affairsWorkflow.getWorkflowId());
			nodeList.add(workerNode);

			workerNodeUser.setId(UUIDGenUtil.generate());
			workerNodeUser.setWorkflowId(affairsWorkflow.getWorkflowId());
			workerNodeUser.setWorkflowNodeId(workerNode.getWorkflowNodeId());
			workerNodeUser.setExamineUserId(0L);
			userList.add(workerNodeUser);

			i = 2;
		}

		// 流程节点列表
		List<AffairsWorkflowNodeVo> nodeVoList = affairsWorkflowVo.getNodeList();
		if (nodeVoList != null && nodeVoList.size() > 0) {
			for (AffairsWorkflowNodeVo nodeVo : nodeVoList) {
				i++;
				AffairsWorkflowNode node = new AffairsWorkflowNode();
				node.setWorkflowNodeId(UUIDGenUtil.generate());
				node.setWorkflowNodeName(nodeVo.getWorkflowNodeName());
				node.setWorkflowNodeIndex(i);
				node.setWorkflowNodeIslast(nodeVoList.size() == i-2 ? CommonConstant.YesNo.YES : CommonConstant.YesNo.NO);
				node.setWorkflowId(affairsWorkflow.getWorkflowId());
				nodeList.add(node);

				// 流程节点对应的审核人列表
				List<AffairsWorkflowNodeUserVo> userVoList = nodeVo.getUserList();
				if (userVoList != null && userVoList.size() > 0) {
					for (AffairsWorkflowNodeUserVo userVo : userVoList) {
						AffairsWorkflowNodeUser user = new AffairsWorkflowNodeUser();
						user.setId(UUIDGenUtil.generate());
						user.setWorkflowId(affairsWorkflow.getWorkflowId());
						user.setWorkflowNodeId(node.getWorkflowNodeId());
						user.setExamineUserId(userVo.getExamineUserId());
						userList.add(user);
					}
				}
			}

			// 批量保存
			if(nodeList != null && nodeList.size() > 0) {
				affairsWorkflowNodeService.saveBatch(nodeList);
			}

			if(userList != null && userList.size() > 0) {
				affairsWorkflowNodeUserService.saveBatch(userList);
			}
		}
		return true;
	}

	@Override
	public AffairsWorkflow selectWorkflowById(Long workflowId) {
		return baseMapper.selectById(workflowId);
	}

}
